package dcl.software.filesync.client;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.HttpClientBuilder;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;

public class HttpsUtils {
	private static ObjectMapper objectMapper = new ObjectMapper();
	private static String baseURL = "http://192.168.1.3:8080/";
	
	public static String getTest(Class<?> klass) throws ClientProtocolException, IOException {
		final String url = baseURL + "authorization/testget";
		CreateUserDTO token = doGet(url, CreateUserDTO.class);
		return token.getUserName();
	}

	public static String createAccount(final CreateUserDTO user) throws ClientProtocolException, IOException {
		final String url = baseURL+"authorization/createaccount";
		StringEntity entity = new StringEntity(objectMapper.writeValueAsString(user));
		entity.setContentType("application/json");
		return doPost(url, entity, String.class);
		/*
		 * final HttpPost request = new HttpPost(url);
		 * request.setEntity(entity); HttpClient client =
		 * HttpClientBuilder.create().build(); final HttpResponse response =
		 * client.execute(request); Header[] allHeaders =
		 * response.getAllHeaders(); HttpEntity entity2 = response.getEntity();
		 * InputStream stream = entity2.getContent(); String token =
		 * readStream(stream, entity2.getContentLength());
		 */
		// return token;
	}
	
	public static String login(final LoginUserDTO user) throws ClientProtocolException, IOException {
		final String url = baseURL+"authorization/login";

		final HttpPost request = new HttpPost(url);
		StringEntity entity = new StringEntity(objectMapper.writeValueAsString(user));
		entity.setContentType("application/json");
		request.setEntity(entity);
		HttpClient client = HttpClientBuilder.create().build();
		final HttpResponse response = client.execute(request);
		Header[] allHeaders = response.getAllHeaders();
		HttpEntity entity2 = response.getEntity();
		InputStream stream = entity2.getContent();
		String token = readStream(stream, entity2.getContentLength());
		return token;
	}

	public static void uploadFile(File file, String token) throws ClientProtocolException, IOException {
		final String url = baseURL+"transfer/addfile";

		Map<String, String> map = new HashMap<>();
		map = FileAnalyzer.getMetadataMap(file);
		FileUploadItem fileItem = new FileUploadItem(file.getName(), file.getAbsolutePath(), MacUtils.getMacAddress(), map);
		HttpEntity entity = createMultipartEntityForFile(file, fileItem);

		final HttpPost request = new HttpPost(url);
		request.setEntity(entity);
		request.addHeader("token", token);
		HttpClient client = HttpClientBuilder.create().build();
		final HttpResponse response = client.execute(request);
		System.out.println(response.getStatusLine().getStatusCode());
	}

	private static <T> T doGet(String url, Class<T> klass) throws JsonParseException, JsonMappingException, ClientProtocolException, IOException {
		final HttpGet request = new HttpGet(url);
		return executeHttp(request, klass);
	}

	private static <T> T doPost(String url, HttpEntity entity, Class<T> klass) throws JsonParseException, JsonMappingException,
	        ClientProtocolException, IOException {
		final HttpPost request = new HttpPost(url);
		request.setEntity(entity);
		return executeHttp(request, klass);
	}

	private static <T> T executeHttp(HttpUriRequest request, Class<T> klass) throws ClientProtocolException, IOException {
		HttpClient client = HttpClientBuilder.create().build();
		final HttpResponse response = client.execute(request);
		ResponseHandler<String> handler = new BasicResponseHandler();
		return (T) objectMapper.readValue(handler.handleResponse(response), klass);
	}
	private static HttpEntity createMultipartEntityForFile(final File file, FileUploadItem properties) throws FileNotFoundException, UnsupportedEncodingException {
		final MultipartEntityBuilder multipartEntity = MultipartEntityBuilder.create();
		if (file != null) {
			multipartEntity.addBinaryBody("file[]", file, ContentType.APPLICATION_OCTET_STREAM, file.getName());
		}
		Gson gson = new Gson(); 
		String json = gson.toJson(properties); 
		multipartEntity.addTextBody("request",json);
		return multipartEntity.build();
	}
	
	private static String readStream(InputStream stream, long size) {
		StringBuilder sb = new StringBuilder();
		for (long i = 0; i < size; i++) {
			try {
				sb.append((char) stream.read());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return sb.toString();
	}
}
